package beautiful.butterfly.drds.binlog.utils;

import beautiful.butterfly.drds.binlog.connection.ConnectionAttributes;
import beautiful.butterfly.drds.binlog.connection.ConnectionFactory;
import beautiful.butterfly.drds.binlog.netty.server.NioSocketChannelExtend;
import beautiful.butterfly.drds.binlog.operation.OpeationEvent;
import beautiful.butterfly.drds.binlog.operation.OpeationEventQueue;
import beautiful.butterfly.drds.binlog.operation.OperationType;
import beautiful.butterfly.drds.binlog.zookeeper.ZooKeepers;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Nettys
{


    // 清理channel的上下文环境
    public static void cleanChannelContext(ChannelHandlerContext channelHandlerContext, Throwable throwable)
    {
        channelHandlerContext.close();
        ConnectionAttributes connectionAttributes = ((NioSocketChannelExtend) channelHandlerContext.channel()).getConnectionAttributes();
        // 及时更新到ZK,写到哪算哪,交给新开的Thread来写
        {
            connectionAttributes.setGlobalValid(false);// 通知其它人该停止处理本连接的数据
            try
            {
                connectionAttributes.getTaskThread().join();// 等待taskThread线程退出
            } catch (InterruptedException e)
            {
                log.error(e.toString());
            }
        }
        // 发送一个消息给OperationServer,告诉它当前机器减少了一个连接
        OpeationEventQueue.addObject(new OpeationEvent(null, OperationType.socket_delete));
        log.debug("send a socket_delete message to operation queue");
        // 通知其它人接力，如果需要的话
        ZooKeepers.deletePath(connectionAttributes.getRunningPath());
        log.error("channel is cleaned");
        // 最后才通知事件处理器，netty这边处理结束了
        ConnectionFactory.remove(StringUtils.union(connectionAttributes.getIp(), "" + connectionAttributes.getPort()));
    }

    // 主动触发此连接的非注册
    public static void triggerChannelClosed(NioSocketChannelExtend nioSocketChannelExtend)
    {
        if (null == nioSocketChannelExtend)
        {
            return;
        }
        log.debug("triggerChannelClosed");
        // 这里必须设置
        nioSocketChannelExtend.getConnectionAttributes().setGlobalValid(false);
        // 这个runnable绝对是线程安全的 :)
        nioSocketChannelExtend.eventLoop().execute(new Runnable()
        {
            @Override
            public void run()
            {
                nioSocketChannelExtend.deregister();
                log.debug("deregister invoked");


            }
        });
    }

}
